#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h> 
#define N 10
#define TASK_NUM 10
//  void     Runchild ()
//{
//  int cnt =5 ;
//  while(cnt)
//  {
//    printf("child pid:%d ,ppid%d\n",getpid() ,getppid());
//    sleep(1);
//    cnt--;
//  }
//}
typedef void( *task_t ) (); //函数指针

task_t  tasks[TASK_NUM];



int AddTask(task_t t );




void task1()
{
  printf("这是一个执行打印日志的任务\n");
}
void task2()
{
  printf("这是一个执行检测网络健康状态的任务\n");
}
void task3()
{
  printf("这是一个进行绘制图形界面的任务\n");
}
 void InitTask()
{
  int i =0 ;
  for(  ; i< TASK_NUM ; i++ )
  {
    tasks[i]=NULL;
  }
  AddTask(task1);
  AddTask(task2 );
  AddTask(task3);
}

int AddTask ( task_t t    )
{
  //找到数组中为空的位置
  int i =0 ;
  for(  ; i< TASK_NUM ; i++ )
  {
    if( tasks[i] == NULL )
    {
      break;
    }
  }
  if( i == TASK_NUM  )
  {
    return  -1 ; 
  }
  tasks[i]=t ; //放任务

  return  0 ;

}



void ExecuteTask()
{
  int i = 0;
  for(  ; i<TASK_NUM ; i++ )
  {
    //如果为空 ，继续走
    if( tasks[i] == NULL )
    {
      continue ;
    }
    //不为空
    tasks[i]();
  }
}


int main()
{
//  for( int i =0 ; i < N ;i ++ )
//  {
//    pid_t id  =  fork();
//    if( id ==0  )
//    {
//      //子进程
//      Runchild ();
//      exit(i);
//    }
//    //父进程 
//    printf("create child process: %d success\n", id);
//  }
////  sleep(10);
//  //等待
//  for( int i = 0 ; i < N  ; i++ )
//  {
////      pid_t id   =  wait(NULL);
//     int status =0 ;
//    pid_t id=    waitpid(-1 , &status ,0 );
//
//     if( id>0 )
//     {
//       printf("wait %d success,exit code:%d\n", id,WEXITSTATUS(status ) )  ; //id ,退出码
//     }
//
//  }
//
//sleep(5);

 pid_t id = fork() ;
 if(id <0)
 {
   perror("fork");
   return 1 ;
 }
 else if( id == 0 )
 {
  //child 
  
  int cnt =5 ;
  while(cnt)
  {
    printf("I am a child ,pid:%d , ppid:%d cnt: %d\n", getpid() , getppid() ,cnt);
    cnt -- ;
    sleep(1);
  }
    exit(11);
 }
  else // parent 
 {
   //int cnt =5  ;
   //while(cnt )
   //{
   // printf("I am a parent ,pid:%d , ppid:%d cnt: %d\n", getpid() , getppid() ,cnt);
   // cnt -- ;
   // sleep(1); 
   //}
   // pid_t ret = wait(NULL);
    
  int status =0 ;//输出型参数
  //操作系统会去找对应id的子进程,并且等待该子进程，如果该子进程退出 ，操作系统会将子进程的退出信息拷贝到status指针所指向的变量当中
  InitTask();
  while(1)  //轮询
  {

  pid_t  ret = waitpid( id, &status , WNOHANG ); //非阻塞等待

    //等待成功
    if( ret >0 ) //id是子进程的pid
    {
      //status存放的是子进程的退出信息
      //7F 0111 1111 
      //0xFF
     // printf("wait success,ret:%d, exit sig : %d, exit code:%d\n", ret, status&0x7F , (status>>8) &0xFF  ); //打印的分别是 id, 信号， 退出码
     
      if(WEXITSTATUS(status) )
      {
          printf("进程是正常跑完的，退出码：%d\n",WEXITSTATUS(status));
      }
      else 
      {
        printf("进程出异常了\n");
      }
       break;
    }
    else if ( ret< 0 ) 
    {
     printf("wait failed\n");
     break;
    }
    else  //ret==0
    {
      
 //   printf("子进程还没有退出我再等等\n") ;
 //   sleep(1);
  ExecuteTask();
  usleep(500000);
    }
  }
  sleep(3);


 }
  return 0 ;
}
